package com.song.rabbitmq.a_simple;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 简单队列 Consumer 消息消费方
 *
 */
public class Consumer {
    public static void main(String[] args) {

        // 1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2.设置连接属性
        connectionFactory.setHost("121.41.53.91");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        connectionFactory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            // 3. 从连接工厂中获取连接
            connection = connectionFactory.newConnection("消费者");
            // 4. 从连接中获取通道Channel
            channel = connection.createChannel();
            // 5. 通过创建交换机，声明队列，绑定关系，路由key，发送消息，和接收消息
            channel.basicConsume("queue1",true, new DeliverCallback(){
                public void handle(String consumerTag, Delivery message) throws IOException {
                    System.out.println("收到消息是:"+new String(message.getBody(),"UTF-8"));
                }
            }, new CancelCallback(){
                public void handle(String consumerTag) throws IOException{
                    System.out.println("接受失败了......");
                }
            });

            System.out.println("开始接收消息");
            System.in.read(); // 的作用是防止程序在接收消息后立即结束而关闭连接。
            /*
                在这段代码中，System.in.read() 的作用是防止程序在接收消息后立即结束而关闭连接。
                在 RabbitMQ 中，消息的发送和接收都是异步的。一旦消费者订阅了队列，它会开始等待消息的到来，一旦有消息到达就会调用 DeliverCallback 对象的 handle 方法进行处理。但是，如果程序没有阻塞在接收消息的过程中，它很可能会在处理完第一个消息后立即退出，并关闭与 RabbitMQ 的连接。
                为了避免这种情况发生，我们通常会在程序代码的最后添加 System.in.read() 或其他类似的阻塞代码，以防止程序过早退出。在本例中，System.in.read() 让程序挂起，等待用户从控制台输入任意字符后才会结束。这样，即使没有消息到达，程序也不会立即退出，而是持续等待新的消息到来。
                需要注意的是，在生产环境中，您可能不希望使用 System.in.read() 这种阻塞式的代码来保持应用程序的活性。相反，您可以使用一些更先进的技术，例如线程池或消息监听器等，来实现更可靠的消息处理。
             */


        }catch (Exception e){
            e.printStackTrace();
            System.out.println("接收消息出现异常...");
        }finally {
            // 7.释放连接关闭通道
            if (channel != null && channel.isOpen()){
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null){
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }

}
